home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DELPHI32 / EDIT_UTL / DBRICH / DBRICH.PAS next >
Pascal/Delphi Source File  |  1996-03-31  |  9KB  |  332 lines

  1. unit dbrich;
  2.  
  3. {Writen by
  4. Sean Cross
  5. Sean@CRM.co.nz
  6. c/o 11 Albert St
  7. Waipukurau
  8. New Zealand
  9.  
  10. Borland TDBMemo code modified to use RichEdit component instead.
  11.  
  12. Note Slight bug,  call Tablex.Edit before modifying paragraph properties}
  13.  
  14. interface
  15.  
  16. uses
  17.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  18.   StdCtrls, ComCtrls, DB, DBTables, Menus, ExtCtrls, Mask, Buttons, DBCtrls;
  19. type
  20.   TDBRichEdit = class(TRichEdit)
  21.   private
  22.     FDataLink: TFieldDataLink;
  23.     FAutoDisplay: Boolean;
  24.     FFocused: Boolean;
  25.     FMemoLoaded: Boolean;
  26.     FPaintControl: TPaintControl;
  27.     procedure DataChange(Sender: TObject);
  28.     procedure EditingChange(Sender: TObject);
  29.     function  GetDataField: string;
  30.     function  GetDataSource: TDataSource;
  31.     function  GetField: TField;
  32.     function  GetReadOnly: Boolean;
  33.     procedure SetDataField(const Value: string);
  34.     procedure SetDataSource(Value: TDataSource);
  35.     procedure SetReadOnly(Value: Boolean);
  36.     procedure SetAutoDisplay(Value: Boolean);
  37.     procedure SetFocused(Value: Boolean);
  38.     procedure UpdateData(Sender: TObject);
  39.     procedure WMCut(var Message: TMessage); message WM_CUT;
  40.     procedure WMPaste(var Message: TMessage); message WM_PASTE;
  41.     procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
  42.     procedure CMExit(var Message: TCMExit); message CM_EXIT;
  43.     procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
  44.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  45.     procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  46.   protected
  47.     procedure Change; override;
  48.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  49.     procedure KeyPress(var Key: Char); override;
  50.     procedure Notification(AComponent: TComponent;
  51.       Operation: TOperation); override;
  52.     procedure WndProc(var Message: TMessage); override;
  53.   public
  54.     constructor Create(AOwner: TComponent); override;
  55.     destructor Destroy; override;
  56.     procedure  LoadMemo;
  57.     property   Field: TField read GetField;
  58.   published
  59.     property AutoDisplay: Boolean read FAutoDisplay write SetAutoDisplay default True;
  60.     property DataField: string read GetDataField write SetDataField;
  61.     property DataSource: TDataSource read GetDataSource write SetDataSource;
  62.     property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  63.   end;
  64.  
  65. procedure Register;
  66.  
  67. implementation
  68.  
  69. procedure Register;
  70. begin
  71.   RegisterComponents('Data Controls', [TDBRichEdit]);
  72. end;
  73.  
  74. {Mostly copied from DBMemo}
  75.  
  76. constructor TDBRichEdit.Create(AOwner: TComponent);
  77. begin
  78.   inherited Create(AOwner);
  79.   inherited ReadOnly := True;
  80.   FAutoDisplay := True;
  81.   FDataLink := TFieldDataLink.Create;
  82.   FDataLink.Control := Self;
  83.   FDataLink.OnDataChange := DataChange;
  84.   FDataLink.OnEditingChange := EditingChange;
  85.   FDataLink.OnUpdateData := UpdateData;
  86.   FPaintControl := TPaintControl.Create(Self, 'EDIT');
  87. end;
  88.  
  89. destructor TDBRichEdit.Destroy;
  90. begin
  91.   FPaintControl.Free;
  92.   FDataLink.Free;
  93.   FDataLink := nil;
  94.   inherited Destroy;
  95. end;
  96.  
  97. procedure TDBRichEdit.Notification(AComponent: TComponent;
  98.   Operation: TOperation);
  99. begin
  100.   inherited Notification(AComponent, Operation);
  101.   if (Operation = opRemove) and (FDataLink <> nil) and
  102.     (AComponent = DataSource) then DataSource := nil;
  103. end;
  104.  
  105. procedure TDBRichEdit.KeyDown(var Key: Word; Shift: TShiftState);
  106. begin
  107.   inherited KeyDown(Key, Shift);
  108.   if FMemoLoaded then
  109.   begin
  110.     if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
  111.       FDataLink.Edit;
  112.   end else
  113.     Key := 0;
  114. end;
  115.  
  116. procedure TDBRichEdit.KeyPress(var Key: Char);
  117. begin
  118.   inherited KeyPress(Key);
  119.   if FMemoLoaded then
  120.   begin
  121.     if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
  122.       not FDataLink.Field.IsValidChar(Key) then
  123.     begin
  124.       MessageBeep(0);
  125.       Key := #0;
  126.     end;
  127.     case Key of
  128.       ^H, ^I, ^J, ^M, ^V, ^X, #32..#255:
  129.         FDataLink.Edit;
  130.       #27:
  131.         FDataLink.Reset;
  132.     end;
  133.   end else
  134.   begin
  135.     if Key = #13 then LoadMemo;
  136.     Key := #0;
  137.   end;
  138. end;
  139.  
  140. procedure TDBRichEdit.Change;
  141. begin
  142.   with FdataLink do
  143.   begin
  144.     {if Assigned(FdataLink) and (Assigned(DataSource))and (DataSource.State = dsBrowse) then
  145.       Edit; } {make sure edits on Attributes change}
  146.     if FMemoLoaded then Modified;
  147.   end;
  148.   FMemoLoaded := True;
  149.   inherited Change;
  150. end;
  151.  
  152. function TDBRichEdit.GetDataSource: TDataSource;
  153. begin
  154.   Result := FDataLink.DataSource;
  155. end;
  156.  
  157. procedure TDBRichEdit.SetDataSource(Value: TDataSource);
  158. begin
  159.   FDataLink.DataSource := Value;
  160.   if Value <> nil then Value.FreeNotification(Self);
  161. end;
  162.  
  163. function TDBRichEdit.GetDataField: string;
  164. begin
  165.   Result := FDataLink.FieldName;
  166. end;
  167.  
  168. procedure TDBRichEdit.SetDataField(const Value: string);
  169. begin
  170.   FDataLink.FieldName := Value;
  171. end;
  172.  
  173. function TDBRichEdit.GetReadOnly: Boolean;
  174. begin
  175.   Result := FDataLink.ReadOnly;
  176. end;
  177.  
  178. procedure TDBRichEdit.SetReadOnly(Value: Boolean);
  179. begin
  180.   FDataLink.ReadOnly := Value;
  181. end;
  182.  
  183. function TDBRichEdit.GetField: TField;
  184. begin
  185.   Result := FDataLink.Field;
  186. end;
  187.  
  188. procedure TDBRichEdit.LoadMemo;
  189. var BS: tBlobStream;
  190. begin
  191.   if not FMemoLoaded and (FDataLink.Field is TBlobField) then
  192.   begin
  193.     try
  194.       BS := tBlobStream.Create(TBlobField(FDataLink.Field), bmRead);
  195.       Lines.LoadFromStream(BS);
  196.       BS.Free;
  197.       {Lines.Text := FDataLink.Field.AsString;}
  198.       FMemoLoaded := True;
  199.     except
  200.       Lines.Text := 'Error in TDBRichEdit.LoadMemo.  Memo too large?';
  201.     end;
  202.     EditingChange(Self);
  203.   end;
  204. end;
  205.  
  206. procedure TDBRichEdit.DataChange(Sender: TObject);
  207. begin
  208.   if FDataLink.Field <> nil then
  209.     if FDataLink.Field is TBlobField then
  210.     begin
  211.       if FAutoDisplay or (FDataLink.Editing and FMemoLoaded) then
  212.       begin
  213.         FMemoLoaded := False;
  214.         LoadMemo;
  215.       end else
  216.       begin
  217.         Lines.Text := '(' + FDataLink.Field.DisplayLabel + ')';
  218.         FMemoLoaded := False;
  219.       end;
  220.     end else
  221.     begin
  222.       if FFocused and FDataLink.CanModify then
  223.         Lines.Text := FDataLink.Field.Text
  224.       else
  225.         Lines.Text := FDataLink.Field.DisplayText;
  226.       FMemoLoaded := True;
  227.     end
  228.   else
  229.   begin
  230.     if csDesigning in ComponentState then Text := Name else Text := '';
  231.     FMemoLoaded := False;
  232.   end;
  233. end;
  234.  
  235. procedure TDBRichEdit.EditingChange(Sender: TObject);
  236. begin
  237.   inherited ReadOnly := not (FDataLink.Editing and FMemoLoaded);
  238. end;
  239.  
  240. procedure TDBRichEdit.UpdateData(Sender: TObject);
  241. var BS : tBlobStream; 
  242. begin
  243.   {FDataLink.Field.AsString := Lines.Text;}
  244.   BS := tBlobStream.Create(TBlobField(FDataLink.Field), bmWrite);
  245.   Lines.SaveToStream(BS);
  246.   BS.Free;
  247. end;
  248.  
  249. procedure TDBRichEdit.SetFocused(Value: Boolean);
  250. begin
  251.   if FFocused <> Value then
  252.   begin
  253.     FFocused := Value;
  254.     if not (FDataLink.Field is TBlobField) then FDataLink.Reset;
  255.   end;
  256. end;
  257.  
  258. procedure TDBRichEdit.WndProc(var Message: TMessage);
  259. begin
  260.   with Message do
  261.     if (Msg = WM_CREATE) or (Msg = WM_WINDOWPOSCHANGED) or
  262.       (Msg = CM_FONTCHANGED) then FPaintControl.DestroyHandle;
  263.   inherited;
  264. end;
  265.  
  266. procedure TDBRichEdit.CMEnter(var Message: TCMEnter);
  267. begin
  268.   SetFocused(True);
  269.   inherited;
  270. end;
  271.  
  272. procedure TDBRichEdit.CMExit(var Message: TCMExit);
  273. begin
  274.   if FDataLink.Field is TBlobField then
  275.     try
  276.       FDataLink.UpdateRecord;
  277.     except
  278.       SetFocus;
  279.       raise;
  280.     end;
  281.   SetFocused(False);
  282.   inherited;
  283. end;
  284.  
  285. procedure TDBRichEdit.SetAutoDisplay(Value: Boolean);
  286. begin
  287.   if FAutoDisplay <> Value then
  288.   begin
  289.     FAutoDisplay := Value;
  290.     if Value then LoadMemo;
  291.   end;
  292. end;
  293.  
  294. procedure TDBRichEdit.WMLButtonDblClk(var Message: TWMLButtonDblClk);
  295. begin
  296.   if not FMemoLoaded then LoadMemo else inherited;
  297. end;
  298.  
  299. procedure TDBRichEdit.WMCut(var Message: TMessage);
  300. begin
  301.   FDataLink.Edit;
  302.   inherited;
  303. end;
  304.  
  305. procedure TDBRichEdit.WMPaste(var Message: TMessage);
  306. begin
  307.   FDataLink.Edit;
  308.   inherited;
  309. end;
  310.  
  311. procedure TDBRichEdit.CMGetDataLink(var Message: TMessage);
  312. begin
  313.   Message.Result := Integer(FDataLink);
  314. end;
  315.  
  316. procedure TDBRichEdit.WMPaint(var Message: TWMPaint);
  317. var
  318.   S: string;
  319. begin
  320.   if not (csPaintCopy in ControlState) then inherited else
  321.   begin
  322.     if FDataLink.Field <> nil then
  323.       if FDataLink.Field is TBlobField then
  324.         S := AdjustLineBreaks(FDataLink.Field.AsString) else
  325.         S := FDataLink.Field.DisplayText;
  326.     SendMessage(FPaintControl.Handle, WM_SETTEXT, 0, Integer(PChar(S)));
  327.     SendMessage(FPaintControl.Handle, WM_PAINT, Message.DC, 0);
  328.   end;
  329. end;
  330.  
  331. end.
  332.